package com.example.demo.utils;

import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component("activitiUtils")
public class ActivitiUtils {

	@Autowired
	HistoryService historyService;

	@Autowired
	RuntimeService runtimeService;

	@Autowired
	RepositoryService repositoryService;

	@Autowired
	TaskService taskService;

	/**
	 * 部署流程
	 */
	public void createProcessIns() {
		repositoryService.createDeployment().name("请假审批流程").addClasspathResource("processes/leave.bpmn")
				.addClasspathResource("processes/leave.png").deploy();
	}

	/**
	 * 启动流程
	 *
	 * @param bussinessId
	 * @param userId
	 * @param reason
	 * @param day
	 */
	public void startProcess(String bussinessId, String userId, String reason, String day) {

		Map<String, Object> variables = new HashMap<>();
		variables.put("userId", userId);
		variables.put("reason", reason);
		variables.put("day", day);
		runtimeService.startProcessInstanceByKey("leaveProcess", bussinessId, variables);
	}

	/**
	 * 删除流程
	 *
	 * @param deploymentId
	 */
	public void deleteProcess(String deploymentId) {
		repositoryService.deleteDeployment(deploymentId, true);
	}

	/**
	 * 挂起流程
	 *
	 * @param processDefinitionKey
	 */
	public void suspend(String processDefinitionKey) {
		repositoryService.suspendProcessDefinitionByKey(processDefinitionKey, true, null);
	}

	/**
	 * 激活流程
	 *
	 * @param processDefinitionKey
	 */
	public void activate(String processDefinitionKey) {
		repositoryService.activateProcessDefinitionByKey(processDefinitionKey, true, null);
	}

	/**
	 * 部署ID列表
	 */
	public void processDefintion() {
		repositoryService.createDeploymentQuery().orderByDeploymentId().list();
	}

	/**
	 * 获取task数据,设置所属者
	 */
	public void setOwner(String bussinessId, String userId) {
		Task task = taskService.createTaskQuery().processInstanceBusinessKey(bussinessId).singleResult();
		taskService.setOwner(task.getId(), userId);
	}

	/**
	 * 根据taskId获取到task
	 *
	 * @param taskId
	 * @return
	 */
	public Task getTaskByTaskId(String taskId) {
		// 得到当前的任务
		Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
		return task;
	}

	/**
	 * 根据Task中的流程实例的ID，来获取对应的流程实例
	 *
	 * @param task 流程中的任务
	 * @return
	 */
	public ProcessInstance getProcessInstanceByTask(Task task) {
		// 得到当前任务的流程
		ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
				.processInstanceId(task.getProcessInstanceId()).singleResult();
		return processInstance;
	}

	/**
	 * 根据taskId获取到businesskey
	 *
	 * @param taskId 任务的ID
	 */
	public String getBusinessKeyByTaskId(String taskId) {
		Task task = this.getTaskByTaskId(taskId);
		ProcessInstance processInstance = this.getProcessInstanceByTask(task);
		return processInstance.getBusinessKey();
	}

	/**
	 * 进入下一级审批(完成任务)
	 */
	public void nextTask(String taskId) {
		taskService.complete(taskId);
	}

	/**
	 * 进入下一级审批,并进行下一个节点的审批人员的信息的传递
	 */
	public void nextTaskWithMap(String taskId, Object object) {
		Map<String, Object> map = new HashMap<>();
		map.put("user", object);
		taskService.complete(taskId, map);
	}

	/**
	 * 查询历史流程实例
	 *
	 * @param processDefinitionId
	 */
	public List<HistoricProcessInstance> findHisProcessInstance(String processDefinitionId) {
		List<HistoricProcessInstance> list = historyService.createHistoricProcessInstanceQuery()
				.processDefinitionId(processDefinitionId)// 流程定义ID
				.list();
		return list;

	}

	/**
	 * 根据流程ID获取流程图
	 *
	 * @param pid
	 * @return
	 */
	public InputStream lookProcessPicture(String pid) {
		return repositoryService.getProcessDiagram(pid);
	}

	/**
	 * 流程定义列表
	 *
	 * @return
	 */
	public List<ProcessDefinition> findProcessDefinition() {
		List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery()
				.orderByProcessDefinitionVersion().desc().list();
		return list;
	}
}
